package com.tianyu.service.other;

import com.alibaba.fastjson2.JSON;
import com.tianyu.common.RSAEncryptionTool;
import com.tianyu.model.dto.AccessInfo;
import com.tianyu.model.ro.ServiceRo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import java.util.Base64;
import java.util.Map;
import java.util.TreeMap;

/**********************************
 * @Author YSW
 * @Description
 * @Date 2024/7/15 - 11:44
 **********************************/

@Slf4j
@Service
public class ApiService {

    public ServiceRo<?> validationSign(Map<String, String> headerMap, TreeMap<String, Object> body,String privateKeyPem) {
        String sign = headerMap.get("sign");
        if (!StringUtils.hasText(sign)) {
            log.warn("sign invalid.");
            return ServiceRo.resultFailed("sign invalid.");
        }
        String authorization = headerMap.get("authorization");
        String timestamp = headerMap.get("timestamp");
        String method = headerMap.get("method");
        String tid = headerMap.get("tid");
        // 平台私钥串解密
        String authToken = new String(RSAEncryptionTool.decrypt(Base64.getDecoder().decode(authorization), privateKeyPem));
        // body请求体转换Map（按key排序）
        // 将请求体和请求头内容合并
        body.put(".tid", tid);
        body.put(".method", method);
        body.put(".timestamp", timestamp);
        body.put(".Auth-Token", authToken);
        // 将请求内容MD5签名
        final String jsonString = JSON.toJSONString(body);
        String paramsSign = RSAEncryptionTool.getMD5Hash(Base64.getEncoder().encodeToString(jsonString.getBytes()));
        // 签名不匹配！参数可能被篡改
        if (!sign.equals(paramsSign)) {
            log.error("sign => {}, validSign => {}", sign, paramsSign);
            return ServiceRo.resultFailed("签名不匹配！参数可能被篡改");
        }
        long ts;
        try {
            ts = Long.parseLong(timestamp);
        } catch (NumberFormatException e) {
            log.error("timestamp invalid => {}", timestamp);
            return ServiceRo.resultFailed("timestamp invalid.");
        }
//        // 签名有效时间内限制：秒s TODO
//        int sec = 60;
//        // 签名已超时！
//        if (System.currentTimeMillis() - ts > sec * 1000) {
//            log.error("timestamp timeout => {}", timestamp);
//            return ServiceRo.resultFailed("timestamp timeout.");
//        }
        log.info("验签通过. [tid]:{}", tid);
        return ServiceRo.resultSuccess();
    }




    // 分隔符
    public static final String CIPHER_SEPARATOR = "@@:";

    public static void main(String[] args) {
        final AccessInfo accessInfo = new ApiService().getAccessInfo("QSNUYKgj6yYifs1hGxmjb35UtG319nqq2B6plYPA7Peov35icnWy7dWc8wOAXZQsZqDo6BXp2KWRy93XHUb08EUUDo0nRo/ikluMOy6ut/zEfpNRyWD4Or+aFArhrvxS6+Jweh3to8ciZdhXNW7k4OwWUy1TX/rThZCk4N3VDonpCPKy9lhnxngtzB39y65l0gINdqDZdLeDsmmg02n2AfmTTQ3tjaayPAQ1C41pN2Vtxwu1f8U79Sorb9pYa8fJI17wlIVRF+ceteUYgOsKnD5ECgaQkGFe7jvXJgKb9/ZKq2avCdBi2/Y0ZKuV4YCIBssb0fxId1LDb7JcJwn+Ng==");
        System.out.println(accessInfo);
    }

    /**
     * 获取authorization信息
     */
    public AccessInfo getAccessInfo(String authorization) {
        if (!StringUtils.hasText(authorization)) {
            return null;
        }
        String encodedText = null;
        try {
            encodedText = new String(Base64.getDecoder().decode(authorization));
        } catch (Exception ignored) {
        }
        if (encodedText == null) {
            return null;
        }
        String[] akss = deCipher(encodedText);
        if (akss.length <= 1) {
            return null;
        }
        AccessInfo ti = new AccessInfo();
        ti.setAppKey(akss[0]);
        ti.setDigest(akss[1]);
        try {
            String[] tcrd = deCipher(new String(Base64.getDecoder().decode(akss[0])));
            ti.setCode(tcrd[0]);
            ti.setRegisterDate(tcrd[1]);
        } catch (Exception ignored) {
        }
        return ti;
    }

    public static String[] deCipher(String ciphertext) {
        return ciphertext.split(CIPHER_SEPARATOR);
    }
}
